package netty.websocket;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.enums.MsgTypeEnum;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import netty.config.RabbitConfig;
import com.ruoyi.common.core.dto.ChatMsg;
import com.ruoyi.common.core.dto.DataContent;
import netty.session.UserChannelSession;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;

@Component
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private final RabbitTemplate rabbitTemplate;
    public ChatHandler(RabbitTemplate rabbitTemplate){
        this.rabbitTemplate=rabbitTemplate;
    }

    //用于记录和管理所有客户端的channel组
    public static ChannelGroup clients=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame msg) throws Exception {
        //获取channel
        Channel channel = channelHandlerContext.channel();
        String currentLongChannelId=channel.id().asLongText();
        String currentShortChannelId=channel.id().asShortText();

        String text = msg.text();
        System.out.println("接收到的数据"+text);
        DataContent dataContent = JSON.parseObject(text, DataContent.class);
        ChatMsg chatMsg = dataContent.getChatMsg();
        String receiver=chatMsg.getReceiverId();
        String sender=chatMsg.getSenderId();
        chatMsg.setChatTime(LocalDateTime.now());
        Integer msgType = chatMsg.getMsgType();
        if(MsgTypeEnum.CONNECT_INIT.getType().equals(msgType)){
            UserChannelSession.putMultiChannels(sender,channel);
            UserChannelSession.putUserChannelIdRelation(currentLongChannelId,sender);
            System.out.println("首次连接，加入会话组");
            System.out.println(UserChannelSession.getMultiSession(sender));
            System.out.println(UserChannelSession.getUserIdByChannelId(currentLongChannelId));
        }
        //发送消息给receiver
        if(MsgTypeEnum.WORDS.getType().equals(msgType)){
            //发送MQ,去存储该条消息
            rabbitTemplate.convertAndSend(RabbitConfig.CHAT_EXCHANGE,RabbitConfig.CHAT_TOPIC,JSON.toJSONString(chatMsg));
        }
        System.out.println("客户端currentLongChannelId"+currentLongChannelId);
        System.out.println("客户端currentShortChannelId"+currentShortChannelId);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String currentLongChannelId=channel.id().asLongText();
        System.out.println("客户端连接，长ID："+currentLongChannelId);
        //存入channelGroup中进行管理
        clients.add(channel);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String currentLongChannelId=channel.id().asLongText();
        System.out.println("客户端关闭，长ID："+currentLongChannelId);
        String userId = UserChannelSession.getUserIdByChannelId(channel.id().asLongText());
        UserChannelSession.removeChannelList(userId,currentLongChannelId);
        clients.remove(channel);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel channel = ctx.channel();
        String currentLongChannelId=channel.id().asLongText();
        System.out.println("服务端异常，长ID："+currentLongChannelId+"原因"+cause.getLocalizedMessage());
        String userId = UserChannelSession.getUserIdByChannelId(channel.id().asLongText());
        UserChannelSession.removeChannelList(userId,currentLongChannelId);
        ctx.channel().close();
        clients.remove(channel);
    }
}
